
class Person {
    // 声明构造器当中的属性的类型
    name: string;
    age: number
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }
    // 原型对象上的方法
    jump(a: string): string {
        return a + this.name
    }
    // class类自身上的方法
    static run(x: number): number {
        return x
    }
}


let tom = new Person('tom', 18);

// 如何调用原型对象上的方法  ----》使用实例对象可以通过隐式原型链访问到原型对象上的方法
console.log(tom.jump('aa'));

// class类或者构造函数自身上的方法如何调用   对象自身上的方法  obj.xxx  obj['xxx']

console.log(Person.run(5));


// 使用接口规定类的数据类型
interface Anima {
    sound(str: string): string,
    weight(num: number): number
}
// 接口定义类的数据类型时，class 类名 implements  接口{}
/* class Cat implements Anima {
    sound(a: string): string {
        return a
    }
    weight(num: number): number {
        return num
    }
  
} */
/* 
哲书：你今天中午想吃面条
妈妈：米饭
媳妇：水饺


你没有媳妇  听你妈妈的  米饭
你有媳妇    都听    吃米饭 和水饺


有class类 Cat

有一个接口Animal
cat根据Animal这个接口的规则去创建

Animal1 
Cat  既遵循Animal  Animal1都得遵循



*/



interface Anima1 {
    name(str: string): string
}
// 一个类可以使用多个接口进行规定
class Cat implements Anima, Anima1 {
    sound(a: string): string {
        return a
    }
    weight(num: number): number {
        return num
    }
    name(str: string): string {
        return str
    }

}



let kitty = new Cat();
console.log(kitty);
console.log(kitty.sound('喵喵'));
console.log(kitty.sound('汪汪的叫了'));

// 接口可以继承

interface DogInP {
    sound(str: string): string,
}

interface DogInC {
    run(num: number): number
}

// 当前有两个接口,需求是创建一个Dog类，该类通过 两个接口进行类型规定，这个Dog类既有sound  run函数

/* class Dog implements DogInP, DogInC {
    sound(str: string): string {
        return str
    }
    run(num: number): number {
        return num
    }
}

let dahuang = new Dog()
console.log(dahuang); */

// 有两个接口单写有点麻烦 合并成一个
// 接口继承接口
interface NewIn extends DogInP, DogInC {

}
class Dog implements NewIn {
    sound(str: string): string {
        return str
    }
    run(num: number): number {
        return num
    }
}

let dahuang = new Dog()
console.log(dahuang.sound('汪汪汪'));
console.log(dahuang.run(100));


// 在ts中写的变量 函数 对象。。。。都要规定数据类型

// class类的继承
class Students extends Person {
    sex: string;
    // 进行规定构造器当中参数的数据类型
    constructor(name: string, age: number, sex: string) {
        super(name, age);
        this.sex = sex;
    }
    jump(a: string): string {
        return super.jump(a);
    }
}
let sizhe = new Students('sizhe', 15, "男");
console.log(sizhe.jump('2米高'));

// Students称为Person的子类，派生类
// Person 父类  基类  超类


// 修饰符
/* 
public 默认值哪里都有访问
private 私有的 只有内部可以访问
protected 受保护的 只有内部和子类可以访问


*/

class Book {
    // 
    public name: string;
    private price: string;
    protected pages: number;
    constructor(name: string, price: string, pages: number) {
        this.name = name;
        this.price = price;
        this.pages = pages;
    }
    sayBookName(): string {
        // 在class内部
        console.log(this.price);
        console.log(this.pages);
        // 在class类内部访问
        return this.name
    }
}

// 四大名著  水浒传 西游记 红楼梦 三国演义
let hongloumeng = new Book('hongloumeng', '200块', 1500);
console.log(hongloumeng.name);
console.log(hongloumeng);
console.log(hongloumeng.sayBookName());
// 在class外部
// console.log(hongloumeng.price);
// console.log(hongloumeng.pages);

//protected内部和子类中可以访问 外部不能访问
class HouBook extends Book {
    constructor(name: string, price: string, pages: number) {
        super(name, price, pages);
    }
    testPrice() {
        console.log(this.name);
        // console.log(this.price);
        console.log(this.pages);

    }
}

let xiaohongshu = new HouBook('hongshu', '10块', 1000);
console.log(xiaohongshu.testPrice());

export {
    tom,
}

